package com.powernode.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.powernode.constant.BusinessEnum;
import com.powernode.domain.Basket;
import com.powernode.domain.Sku;
import com.powernode.ex.handler.BusinessException;
import com.powernode.feign.CartProductFeign;
import com.powernode.mapper.BasketMapper;
import com.powernode.model.CartItem;
import com.powernode.model.CartVo;
import com.powernode.model.Result;
import com.powernode.model.ShopCart;
import com.powernode.service.BasketService;
import com.powernode.util.AuthUtils;
import com.powernode.vo.CartTotalAmount;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author 贺
* @description 针对表【basket(购物车)】的数据库操作Service实现
* @createDate 2024-07-25 12:43:44
*/
@Service
public class BasketServiceImpl extends ServiceImpl<BasketMapper, Basket>
    implements BasketService{

    @Resource
    private BasketMapper basketMapper;
    @Resource
    private CartProductFeign cartProductFeign;

    /**
     * 查询会员购物车中商品数量
     * 计算方式：购物车中所有商品购买数量的和
     * @param openId
     * @return
     */
    @Override
    public Integer queryMemberBasketProdCount(String openId) {
        List<Object> objs = basketMapper.selectObjs(new QueryWrapper<Basket>()
                .select("ifnull(sum(prod_count), 0)")
                .eq("open_id", openId));
        Object o = objs.get(0);
        return Integer.valueOf(o.toString());
    }

    /**
     * 查询会员购物车页面数据
     *
     * @param openId
     * @return
     */
    @Override
    public CartVo queryMemberCartVo(String openId) {
        // 创建购物车对象
        CartVo cartVo = new CartVo();

        // 查询会员购物车记录集合
        List<Basket> basketList = basketMapper.selectList(new LambdaQueryWrapper<Basket>()
                .eq(Basket::getOpenId, openId));
        // 判断会员购物车记录集合是否为空
        if (CollectionUtil.isEmpty(basketList) || basketList.size() == 0) {
            return cartVo;
        }

        // 从购物车记录集合中获取商品skuId集合
        List<Long> skuIdList = basketList.stream().map(Basket::getSkuId).collect(Collectors.toList());

        // 远程调用：根据skuId集合查询商品sku对象集合
        Result<List<Sku>> skuListResult = cartProductFeign.getSkuListByIds(skuIdList);
        // 判断远程调用结果是否成功
        if (BusinessEnum.OPERATION_FAIL.getCode().equals(skuListResult.getCode())) {
            throw new BusinessException("用商品服务接口失败：根据skuId集合查询sku对象集合");
        }

        // 获取购物车商品sku对象集合
        List<Sku> skuList = skuListResult.getData();

        // 创建购物车店铺对象集合
        List<ShopCart> shopCartList = new ArrayList<>();

        // 遍历会员购物车记录集合
        basketList.forEach(basket -> {
            // 获取当前购物车记录对象的basketId
            Long basketId = basket.getBasketId();
            // 获取当前购物车记录对象的shopId
            Long shopId = basket.getShopId();
            // 获取当前购物车记录对象的prodId
            Long prodId = basket.getProdId();
            // 获取当前购物车记录对象的skuId
            Long skuId = basket.getSkuId();
            // 获取当前购物车记录对象的prodCount
            Integer prodCount = basket.getProdCount();


            // 判断当前购物车记录所属的店铺是否在购物车店铺对象集合中存在
            List<ShopCart> oneShopCartList = shopCartList.stream().filter(shopCart -> shopCart.getShopId().equals(shopId)).collect(Collectors.toList());
            if (CollectionUtil.isEmpty(oneShopCartList) || oneShopCartList.size() == 0) {
                // 集合为空，当前购物车记录所属的店铺在购物车店铺对象集合中不存在，需要创建购物车店铺对象
                // 创建购物车店铺对象
                ShopCart shopCart = new ShopCart();

                // 创建购物车商品条目对象集合
                List<CartItem> cartItemList = new ArrayList<>();

                // 创建购物车商品条目对象
                CartItem cartItem = new CartItem();

                // 给购物车商品条目对象的属性赋值
                cartItem.setBasketId(basketId);
                cartItem.setProdId(prodId);
                cartItem.setSkuId(skuId);
                cartItem.setProdCount(prodCount);
                // 从商品sku对象集合中获取当前购物车记录对应的sku对象
                Sku sku = skuList.stream().filter(s -> s.getSkuId().equals(skuId)).findFirst().get();
                // 属性拷贝，将sku对象属性拷贝到购物车商品条目对象中
                BeanUtil.copyProperties(sku, cartItem);

                cartItemList.add(cartItem);
                shopCart.setShopId(shopId);
                shopCart.setShopCartItems(cartItemList);

                shopCartList.add(shopCart);
            } else {
                // 集合不为空，当前购物车记录所属的店铺在购物车店铺对象集合中存在，不需要再创建购物车店铺对象，只需要从购物车店铺对象集合中获取之前的购物车店铺对象
                // 获取当前购物车记录所属的购物车店铺对象
                ShopCart shopCart = oneShopCartList.get(0);
                // 从购物车店铺对象中获取已有的购物车商品条目对象集合
                List<CartItem> cartItemList = shopCart.getShopCartItems();
                // 将当前购物车记录对应的购物车商品条目对象添加到购物车商品条目对象集合中
                // 创建当前购物车记录对应的购物车商品条目对象
                CartItem cartItem = new CartItem();
                cartItem.setBasketId(basketId);
                cartItem.setProdId(prodId);
                cartItem.setSkuId(skuId);
                cartItem.setProdCount(prodCount);
                // 从商品sku对象集合中获取当前购物车记录对应的sku对象
                Sku sku = skuList.stream().filter(s -> s.getSkuId().equals(skuId)).findFirst().get();
                // 属性拷贝，将sku对象属性拷贝到购物车商品条目对象中
                BeanUtil.copyProperties(sku, cartItem);
                cartItemList.add(cartItem);
                shopCart.setShopCartItems(cartItemList);
            }
        });

        cartVo.setShopCarts(shopCartList);
        return cartVo;
    }

    /**
     * 计算购物车中会员选中商品的金额
     *
     * @param basketIdList
     * @return
     */
    @Override
    public CartTotalAmount calculateMemberCheckedBasketTotalAmount(List<Long> basketIdList) {
        // 创建购物车总金额对象
        CartTotalAmount cartTotalAmount = new CartTotalAmount();

        // 判断会员选中的购物车记录id集合是否为空
        if (CollectionUtil.isEmpty(basketIdList) || basketIdList.size() == 0) {
            return cartTotalAmount;
        }

        // 根据购物车记录id集合查询会员购物车记录对象集合
        List<Basket> basketList = basketMapper.selectBatchIds(basketIdList);

        // 从购物车记录对象集合中获取商品skuId集合
        List<Long> skuIdList = basketList.stream().map(Basket::getSkuId).collect(Collectors.toList());

        // 远程调用：根据skuId集合查询sku对象集合
        Result<List<Sku>> skuListResult = cartProductFeign.getSkuListByIds(skuIdList);
        // 判断远程调用结果是否成功
        if (BusinessEnum.OPERATION_FAIL.getCode().equals(skuListResult.getCode())) {
            throw new BusinessException("用商品服务接口失败：根据skuId集合查询sku对象集合");
        }
        // 获取远程调用结果中的sku对象集合
        List<Sku> skuList = skuListResult.getData();

        // 创建购物车中所有单个商品总金额的集合
        List<BigDecimal> skuTotalAmountList = new ArrayList<>();

        // 遍历购物车记录对象集合
        basketList.forEach(basket -> {
            // 获取购物车记录对象中skuId
            Long skuId = basket.getSkuId();
            // 获取购物车记录对象中商品购买数量
            Integer prodCount = basket.getProdCount();
            // 从sku对象集合中获取当前购物车记录对应的sku对象
            Sku sku = skuList.stream().filter(s -> s.getSkuId().equals(skuId)).findFirst().get();
            // 获取购物车记录对象中的sku对象的价格
            BigDecimal price = sku.getPrice();
            // 计算当前购物车记录中商品的总金额
            BigDecimal oneSkuTotalAmount = price.multiply(new BigDecimal(prodCount));
            // 将当前购物车记录中商品的总金额添加到购物车中所有单个商品总金额的集合中
            skuTotalAmountList.add(oneSkuTotalAmount);
        });

        // 计算购物车中所有单个商品总金额的和
        BigDecimal allSkuTotalAmount = skuTotalAmountList.stream().reduce(BigDecimal.ZERO, BigDecimal::add);

        // 补充购物车总金额对象中的属性值
        cartTotalAmount.setTotalMoney(allSkuTotalAmount);
        cartTotalAmount.setFinalMoney(allSkuTotalAmount);

        // 约定运费规则：满99元免运费，少于99元，运费为6元
        if (allSkuTotalAmount.compareTo(new BigDecimal(99)) < 0) {
            cartTotalAmount.setTransMoney(new BigDecimal(6));
            cartTotalAmount.setFinalMoney(allSkuTotalAmount.add(new BigDecimal(6)));
        }

        return cartTotalAmount;
    }

    /**
     * 添加商品到购物车/修改购物车中商品数量
     *
     * @param basket
     * @return
     */
    @Override
    public Boolean changeCartItem(Basket basket) {
        // 获取当前登录会员的openId
        String openId = AuthUtils.getMemberOpenId();

        // 根据会员openId和skuId查询购物车记录对象
        Basket beforeBasket = basketMapper.selectOne(new LambdaQueryWrapper<Basket>()
                .eq(Basket::getOpenId, openId)
                .eq(Basket::getSkuId, basket.getSkuId()));

        // 判断购物车记录对象是否为空
        if (ObjectUtil.isNotNull(beforeBasket)) {
            // 不为空，要添加到购物车的商品已存在购物车中
            // 修改购物车中该商品的数量
            int finalProdCount = beforeBasket.getProdCount() + basket.getProdCount();
            beforeBasket.setProdCount(finalProdCount);
            return basketMapper.updateById(beforeBasket) > 0;
        }
        // 要添加到购物车的商品不存在购物车中，添加该商品到购物车
        basket.setCreateTime(new Date());
        basket.setOpenId(openId);
        return basketMapper.insert(basket) > 0;
    }
}




